---
title: Working with wgpu-matrix
description: A guide on how to use TypeGPU with wgpu-matrix.
---

The [wgpu-matrix](https://github.com/greggman/wgpu-matrix) library provides utilities for matrix and vector math, which is essential for graphics programming.
It is designed from the ground up to be compatible with WebGPU, and TypeGPU works with it seamlessly.

:::note[Supported versions]
- `wgpu-matrix` — 3.3.0 and up
- `typegpu` — 0.2.0 and up
:::

## Using wgpu-matrix functions with TypeGPU primitives

Because elements in TypeGPU vectors and matrices can be accessed with the `[]` operator, they can be processed by `wgpu-matrix` utilities.
For example, you can create a vector and normalize it like this:

```ts
import * as d from 'typegpu/data';
import { vec2 } from 'wgpu-matrix';

const v = d.vec2f(1, 2);
vec2.normalize(v, v);
console.log(v.x); // 0.447..
console.log(v.y); // 0.894..
```

:::note
Since we want to modify the vector in-place, we pass the same vector as both input and dst arguments.
If we didn't, we would get a `Float32Array` without modifying the original vector.
:::

If you wanted to initialize a matrix as an identity matrix, you could do it like this:

```ts
import * as d from 'typegpu/data';
import { mat4 } from 'wgpu-matrix';

const m = mat4.identity(d.mat4x4f()); // returns a mat4x4f

console.log(m[0]); // 1
```

## Migration tips

Since you can use TypeGPU primitives directly with `wgpu-matrix` functions, the migration process is relatively simple.
Let's look at some examples:

### Chained in-place operations on a matrix

If your code creates a matrix and then applies some operations to it in-place, you can use TypeGPU primitives directly:

```diff lang=ts
-const m = mat4.create();
+const m = mat4x4f();
mat4.identity(m);                   // m = identity
mat4.translate(m, [1, 2, 3], m);    // m *= translation([1, 2, 3])
mat4.rotateX(m, Math.PI * 0.5, m);  // m *= rotationX(Math.PI * 0.5)
mat4.scale(m, [1, 2, 3], m);        // m *= scaling([1, 2, 3])
```

### Creating a matrix using a function

If your code creates a matrix using a function, for example:

```ts
const fov = 60 * Math.PI / 180
const aspect = width / height;
const near = 0.1;
const far = 1000;
const perspective = mat4.perspective(fov, aspect, near, far);
```

You can pass a TypeGPU matrix as the destination argument:

```diff lang=ts
+const m = mat4x4f();
const fov = 60 * Math.PI / 180
const aspect = width / height;
const near = 0.1;
const far = 1000;
-const perspective = mat4.perspective(fov, aspect, near, far);
+mat4.perspective(fov, aspect, near, far, m);
```

:::tip
If you didn't remove the `perspective` variable, it would just become an alias for `m`.
This could be useful if you later use that variable and don't want to replace all occurrences.
:::
